//
//  UIView+Extension.swift
//  SwifterTemplate
//
//  Created by WhatsXie on 2017/9/22.
//  Copyright © 2017年 StevenXie. All rights reserved.
//

import SnapKit
import UIKit

// MARK: - UIView 常用

public extension UIView {
    var x: CGFloat {
        get {
            return frame.origin.x
        } set {
            frame.origin.x = newValue
        }
    }

    var y: CGFloat {
        get {
            return frame.origin.y
        } set {
            frame.origin.y = newValue
        }
    }

    var bottom: CGFloat {
        get {
            return frame.maxY
        } set {
            frame.origin.y = newValue - height
        }
    }

    var left: CGFloat {
        get {
            return frame.minX
        } set {
            frame.origin.x = newValue
        }
    }

    var right: CGFloat {
        get {
            return frame.maxX
        } set {
            frame.origin.x = newValue - width
        }
    }

    var width: CGFloat {
        get {
            return frame.width
        } set {
            frame.size.width = newValue
        }
    }

    var height: CGFloat {
        get {
            return frame.height
        } set {
            frame.size.height = newValue
        }
    }

    var size: CGSize {
        get {
            return frame.size
        } set {
            frame.size = newValue
        }
    }

//    var centerX:CGFloat{
//        get{
//            return self.center.x
//        }set{
//            self.centerX = newValue
//        }
//    }
//
//    var centerY:CGFloat{
//        get{
//            return self.center.y
//        }set{
//            self.centerY = newValue
//        }
//    }

    // 关联 SB 和 XIB
    @IBInspectable var cornerRadius: CGFloat {
        get {
            return layer.cornerRadius
        }

        set {
            layer.cornerRadius = newValue
        }
    }

    @IBInspectable var shadowRadius: CGFloat {
        get {
            return layer.shadowRadius
        }

        set {
            layer.shadowRadius = newValue
        }
    }

    @IBInspectable var shadowOpacity: Float {
        get {
            return layer.shadowOpacity
        }

        set {
            layer.shadowOpacity = newValue
        }
    }

    @IBInspectable var shadowColor: UIColor? {
        get {
            return layer.shadowColor != nil ? UIColor(cgColor: layer.shadowColor!) : nil
        }

        set {
            layer.shadowColor = newValue?.cgColor
        }
    }

    @IBInspectable var shadowOffset: CGSize {
        get {
            return layer.shadowOffset
        }

        set {
            layer.shadowOffset = newValue
        }
    }

    @IBInspectable var zPosition: CGFloat {
        get {
            return layer.zPosition
        }

        set {
            layer.zPosition = newValue
        }
    }

    @IBInspectable
    /// Corner radius of view; also inspectable from Storyboard.
    var maskToBounds: Bool {
        get {
            return layer.masksToBounds
        }
        set {
            layer.masksToBounds = newValue
        }
    }

    @IBInspectable
    /// Should the corner be as circle
    var circleCorner: Bool {
        get {
            return min(bounds.size.height, bounds.size.width) / 2 == cornerRadius
        }
        set {
            cornerRadius = newValue ? min(bounds.size.height, bounds.size.width) / 2 : cornerRadius
        }
    }

    @IBInspectable
    /// Shadow path of view; also inspectable from Storyboard.
    var shadowPath: CGPath? {
        get {
            return layer.shadowPath
        }
        set {
            layer.shadowPath = newValue
        }
    }

    @IBInspectable
    /// Should shadow rasterize of view; also inspectable from Storyboard.
    /// cache the rendered shadow so that it doesn't need to be redrawn
    var shadowShouldRasterize: Bool {
        get {
            return layer.shouldRasterize
        }
        set {
            layer.shouldRasterize = newValue
        }
    }

    @IBInspectable
    /// Should shadow rasterize of view; also inspectable from Storyboard.
    /// cache the rendered shadow so that it doesn't need to be redrawn
    var shadowRasterizationScale: CGFloat {
        get {
            return layer.rasterizationScale
        }
        set {
            layer.rasterizationScale = newValue
        }
    }
}

// MARK: - UIView 显示特性

public extension UIView {
    // MARK: - 转成图片

    func asImage() -> UIImage {
        let renderer = UIGraphicsImageRenderer(bounds: bounds)
        return renderer.image { rendererContext in
            layer.render(in: rendererContext.cgContext)
        }
    }

    // MARK: - 添加阴影

    func addShadowWithColor(color: UIColor = UIColor.black) {
        let path = UIBezierPath(rect: layer.bounds)
        layer.shadowPath = path.cgPath
        layer.shadowColor = color.cgColor
        layer.shadowOffset = CGSize(width: 0, height: 0)
        layer.shadowOpacity = 0.4
        layer.shadowRadius = 8.0
    }

    func addShadow(color: UIColor? = nil,
                   shadowOffset: CGSize? = nil,
                   shadowRadius: CGFloat? = nil,
                   shadowOpacity: Float? = nil) {
        layer.shadowRadius = shadowRadius ?? 12
        layer.shadowOpacity = shadowOpacity ?? 1
        layer.shadowOffset = shadowOffset ?? CGSize(width: 0, height: 8)
        layer.shadowColor = (color ?? UIColor.black.withAlphaComponent(0.06)).cgColor
    }

    func removeAllSubViews() {
        subviews.forEach { $0.removeFromSuperview() }
    }

    // MARK: - 添加圆角

    func setRoundedCorner(radius: CGFloat? = nil) {
        if let radius = radius {
            layer.cornerRadius = radius
        } else {
            layer.cornerRadius = frame.height / 2
        }
    }

    // MARK: - 旋转

    func rotate(_ toValue: CGFloat, duration: CFTimeInterval = 0.2) {
        let animation = CABasicAnimation(keyPath: "transform.rotation")
        animation.toValue = toValue
        animation.duration = duration
        animation.isRemovedOnCompletion = false
        animation.fillMode = CAMediaTimingFillMode.forwards
        layer.add(animation, forKey: nil)
    }

    // MARK: - 添加subView

    func addsubViews(views: [UIView]) {
        views.forEach { view in
            self.addSubview(view)
        }
    }

    @IBInspectable var borderWidth: CGFloat {
        get {
            return layer.borderWidth
        }
        set {
            layer.borderWidth = newValue
        }
    }

    @IBInspectable var borderColor: UIColor? {
        get {
            return UIColor(cgColor: layer.borderColor!)
        }
        set {
            layer.borderColor = newValue?.cgColor
        }
    }

    @IBInspectable var leftBorderWidth: CGFloat {
        get {
            return 0.0 // Just to satisfy property
        }
        set {
            let line = UIView(frame: CGRect(x: 0.0, y: 0.0, width: newValue, height: bounds.height))
            line.translatesAutoresizingMaskIntoConstraints = false
            line.backgroundColor = UIColor(cgColor: layer.borderColor!)
            addSubview(line)

            let views = ["line": line]
            let metrics = ["lineWidth": newValue]
            addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "|[line(==lineWidth)]", options: [], metrics: metrics, views: views))
            addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[line]|", options: [], metrics: nil, views: views))
        }
    }

    @IBInspectable var topBorderWidth: CGFloat {
        get {
            return 0.0 // Just to satisfy property
        }
        set {
            let line = UIView(frame: CGRect(x: 0.0, y: 0.0, width: bounds.width, height: newValue))
            line.translatesAutoresizingMaskIntoConstraints = false
            line.backgroundColor = borderColor
            addSubview(line)

            let views = ["line": line]
            let metrics = ["lineWidth": newValue]
            addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "|[line]|", options: [], metrics: nil, views: views))
            addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[line(==lineWidth)]", options: [], metrics: metrics, views: views))
        }
    }

    @IBInspectable var rightBorderWidth: CGFloat {
        get {
            return 0.0 // Just to satisfy property
        }
        set {
            let line = UIView(frame: CGRect(x: bounds.width, y: 0.0, width: newValue, height: bounds.height))
            line.translatesAutoresizingMaskIntoConstraints = false
            line.backgroundColor = borderColor
            addSubview(line)

            let views = ["line": line]
            let metrics = ["lineWidth": newValue]
            addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "[line(==lineWidth)]|", options: [], metrics: metrics, views: views))
            addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[line]|", options: [], metrics: nil, views: views))
        }
    }

    @IBInspectable var bottomBorderWidth: CGFloat {
        get {
            return 0.0 // Just to satisfy property
        }
        set {
            let line = UIView(frame: CGRect(x: 0.0, y: bounds.height, width: bounds.width, height: newValue))
            line.translatesAutoresizingMaskIntoConstraints = false
            line.backgroundColor = borderColor
            addSubview(line)

            let views = ["line": line]
            let metrics = ["lineWidth": newValue]
            addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "|[line]|", options: [], metrics: nil, views: views))
            addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[line(==lineWidth)]|", options: [], metrics: metrics, views: views))
        }
    }
}

public extension UIResponder {
    // 获取父视图
    func getParentViewController() -> UIViewController? {
        if next is UIViewController {
            return next as? UIViewController
        } else {
            if next != nil {
                return (next!).getParentViewController()
            } else { return nil }
        }
    }
}

public extension UIView {
    /// 返回view依赖的viewController
    var viewController: UIViewController? {
        var responder = self as UIResponder
        while let nextResponder = responder.next {
            if responder is UIViewController {
                return (responder as! UIViewController)
            }
            responder = nextResponder
        }
        return nil
    }

    /// 查找aClass类型的subview（没递归）
    ///
    /// - Parameter aClass: 类的类型
    /// - Returns: 查找aClass类型的subview
    func findSubView(aClass: AnyClass) -> UIView? {
        for subView in subviews {
            if type(of: subView) === aClass {
                return subView
            }
        }
        return nil
    }

    /// 查找aClass类型的superview
    ///
    /// - Parameter aClass: 类的类型
    /// - Returns: 查找aClass类型的superview
    func findSuperView(aClass: AnyClass) -> UIView? {
        guard let parentView = superview else {
            return nil
        }
        if type(of: parentView) === aClass {
            return parentView
        }

        return findSuperView(aClass: aClass)
    }

    // 判断View是不是第一响应者
    func findAndResignFirstResponder() -> Bool {
        if isFirstResponder {
            resignFirstResponder()
            return true
        }
        for v in subviews {
            if v.findAndResignFirstResponder() {
                return true
            }
        }
        return false
    }

    // 找到当前view的第一响应者
    func findFirstResponder() -> UIView? {
        if self is UITextField || self is UITextView, isFirstResponder {
            return self
        }
        for v: UIView in subviews {
            let fv = v.findFirstResponder()
            if fv != nil {
                return fv
            }
        }
        return nil
    }
}

public extension UIView {
    var safeArea: ConstraintBasicAttributesDSL {
        if #available(iOS 11.0, *) {
            return safeAreaLayoutGuide.snp
        }
        return snp
    }

    func add(_ subviews: UIView...) {
        subviews.forEach(addSubview)
    }

    //    func clearSubViews(){
    //        subviews.forEach(UIView.removeFromSuperview)
    //    }

    func hiddenAllSubViews() {
        subviews.forEach { view in
            view.isHidden = true
        }
    }
}
